package design.singleton;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.util.concurrent.CountDownLatch;

public class TestSingleton02 {

    // 静态内部类
    private static class SingletonClassInstance {
        private static final TestSingleton02 instance = new TestSingleton02();
    }

    public static TestSingleton02 getInstance() {
        return SingletonClassInstance.instance;
    }

    public static void main(String[] args) throws Exception {
        TestSingleton02 t1 = TestSingleton02.getInstance();
        TestSingleton02 t2 = TestSingleton02.getInstance();
        System.out.println(t1 == t2);

        TestSingleton03 t3 = TestSingleton03.INSTANCE;
        TestSingleton03 t4 = TestSingleton03.INSTANCE;
        System.out.println(t3 == t4);


        Class<TestSingleton01> clazz = (Class<TestSingleton01>) Class.forName("design.singleton.TestSingleton01");
        Constructor<TestSingleton01> c = clazz.getDeclaredConstructor(null);
        c.setAccessible(true);
        TestSingleton01 s1 = c.newInstance();
        TestSingleton01 s2 = c.newInstance();
        System.out.println(s1);
        System.out.println(s2);


        TestSingleton01 t5 = TestSingleton01.getInstance();
        TestSingleton01 t6 = TestSingleton01.getInstance();
        System.out.println(t5);
        System.out.println(t6);

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
        oos.writeObject(t5);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
        TestSingleton01 t7 = (TestSingleton01) ois.readObject();
        System.out.println(t7);

        long start = System.currentTimeMillis();
        int threadNum = 10;
        final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
        for (int j = 0; j < threadNum; j++) {
            new Thread(() -> {
                for (int i = 0; i < 100000; i++) {
                    Object o = TestSingleton01.getInstance();
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("waste: " + (end - start));

    }
}
